/**
 * 炸金花
 * 炸金花逻辑实现
 * 牌堆一共 52 张牌
 * 分为 4 组，每组 13 张，分别是红心、梅花、方块、黑桃
 * 每组中有 2 3 4 5 6 7 8 9 10 J Q K A
 * 三个 > 清一色 > 顺子 > 对子 > 单牌
 * 而上述循序中最大的牌为 AAA、QKA、QKA、AAK、AKJ
 * 每轮会有一张公共牌，公共牌的花色为最大花色
 * 例如公共牌的花色为黑桃，那么 黑桃的同牌型牌最大，按照 黑桃、梅花、方块、红心 的顺序进行比较
 */
/**
 * 选择玩家数量 => 进入游戏 => 抽取公共牌 √ 
 * 玩家选择发牌（一个玩家[我]，其他的是电脑） => 给所有人发牌
 * 每人最多3张牌 => 发牌完毕 => 开牌比牌面大小
 * 
 * 
 *  豹子：三张数字大小一样
    金花：三张牌花色一样，如三张牌全部是方块、全部是梅花等
    顺子：花色不同的连贯数字组合
    金花顺：金花和顺子全部符合的牌
    对牌：三张牌里面有两张数字相同
    散排：不属于以上任何一种牌的

    牌型比大小规则：从大往小依次为豹子、金花顺、金花、顺子、对子、散牌
 * 
 * 一张牌 例如{
 *    num: 'k', 改为数字类型在需要显示牌面的时候转成字符串好了 => 13
 *    flower: '黑桃',
 * }
 *  
 * 拿到一个玩家的牌组 例如[{
 *    name: '电脑1',
 *    num: 'k',
 *    flower: '黑桃',
 * },{
 *    num: 'A',
 *    flower: '黑桃',
 * },{
 *    num: '2',
 *    flower: '方块',
 * }]
 * 
 * baoziFlag = false
 * duiziFlag = false
 * for (let i = 0 ;i < paizu.length; i++){
 *  let sameIndex = paizu.indexOf(paizu[i].num)
 *  if(sameIndex != -1 && sameIndex != i){
 *   duiziFlag = true 判断对子
 *  }
 *  if(duiziFlag && sameIndex != -1 && sameIndex != i){
 *   baoziFlag = true 判断豹子
 *  }
 * }
 *
 * 金花
 * 
 * 顺子（豹子对子不是顺子）
 * 金花顺（豹子对子不是顺子）
 * 
 * 先判断金花
 * for (let i = 0 ;i < paizu.length; i++){
 *  let sameIndex = paizu.indexOf(paizu[i].flower)
 *  if(sameIndex != -1 && != i){
 *   duizihuaFlag = true 判断对子花色
 *  }
 *  if(duiziFlag && sameIndex != -1 && sameIndex != i){
 *   jinhuaFlag = true 判断金花
 *  }
 * }
 * 再判断顺子
 * for (let i = 0 ;i < paizu.length; i++){
 *  let linkIndex_min = paizu.indexOf((paizu[i].num - 1))
 *  let linkIndex_max = paizu.indexOf((paizu[i].num + 1))
 *  if(linkIndex_min >=0 && linkIndex_max >= 0 && linkIndex_min != i && linkIndex_max != i){
 *    shunziflag = true
 *  }
 * }
 *  
 * 
 * 
 */

import { useEffect, useState } from 'react'
import './index.less'
import { Button, Dropdown, DropdownProps, MessagePlugin } from 'tdesign-react'
import CardItem from './CardItem'

type CardType = {
  num: number,
  flower: string,
  flowerWeight: number,
}

type PlayerType = {
  playerName: string,
  cardList: CardType[],
  decks: string,
  rank: number,
}

const ThreeAceWin = () => {
  const [currentCardList, setCurrentCardList] = useState<CardType[]>([])
  const [broardCard, setBroardCard] = useState<CardType>({
    num: 0,
    flower: '',
    flowerWeight: 0,
  })
  const [playerList, setPlayerList] = useState<PlayerType[]>([])
  const [resList, setResList] = useState<PlayerType[]>([])

  useEffect(() => {
    initCardList()
  }, [])

  useEffect(() => {
    if (currentCardList.length && playerList.length && broardCard.num == 0) {
      getBoardCard()
    }
    console.log('playerList', playerList)
  }, [playerList])


  /**
   * 选择玩家人数,初始化玩家
   */
  const initPlayerList = () => {
    const options = [
      {
        content: '2名玩家',
        value: 2,
      },
      {
        content: '3名玩家',
        value: 3,
      },
      {
        content: '4名玩家',
        value: 4,
      },
      {
        content: '5名玩家',
        value: 5,
      },
      {
        content: '6名玩家',
        value: 6,
      },
    ];
    let playerNumber: number = 0
    let _playerList = []
    const clickHandler: DropdownProps['onClick'] = (data) => {
      playerNumber = data.value as number
      for (let i = 0; i < playerNumber; i++) {
        let obj = {
          playerName: '',
          cardList: [],
          decks: '',
          rank: 0,
        }
        if (i == playerNumber - 1) { //我 后手
          obj.playerName = '我'
        } else {
          obj.playerName = '电脑' + (i + 1)
        }
        _playerList.push(obj)
      }
      setPlayerList(_playerList)
    };
    return (
      <Dropdown options={options} onClick={clickHandler}>
        <Button variant="text">
          选择玩家数量：
        </Button>
      </Dropdown>
    );
  }

  /**
   * 初始化牌堆52张牌
   */
  const initCardList = () => {
    let num = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
    // let card = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
    let flower = ['heitao', 'meihua', 'fangkuai', 'hongxin']
    let cardList: any[] = new Array(52)
    let n = 0
    for (let i = 0; i < num.length; i++) {
      for (let j = 0; j < flower.length; j++) {
        cardList[n] = {
          num: num[i],
          flower: flower[j],
        }
        n++
      }
    }
    setCurrentCardList(cardList)
  }

  /**
   * 随机一张公共牌,牌堆减掉该牌
   */
  const getBoardCard = () => {
    let randomNum = Math.floor(Math.random() * currentCardList.length)
    setBroardCard(currentCardList[randomNum])
    substractCard(randomNum)
  }

  /**
   * 减去一张牌,下标为index
   */
  const substractCard = (cardIndex: number) => {
    let cardList = [...currentCardList]
    cardList.splice(cardIndex, 1)
    setCurrentCardList(cardList)
  }

  /**
   * 玩家随机抽3张牌
   */
  const dealThreeCard = (playerIndex: number) => {
    //三张牌的下标
    let randomList = []
    for (let i = 0; i < 3; i++) {
      let randomNum = Math.floor(Math.random() * currentCardList.length)
      randomList.push(randomNum)
    }
    for (let i = 0; i < 3; i++) {
      if (randomList.indexOf(randomList[i]) != i) { //重复项重新随机一个数（感觉有更好的方法先这样吧）
        randomList[i] = Math.floor(Math.random() * currentCardList.length)
      }
    }

    let _playerList = [...playerList]
    // _playerList[playerIndex].cardList[_playerList[playerIndex].cardList.length-1] = currentCardList[randomNum]
    // _playerList[playerIndex].num = currentCardList[randomNum].num
    // setPlayerList(_playerList)
    // substractCard(randomNum)
  }

  /**
   * 玩家随机抽1张牌 (感觉抽一张比较好，不过要判断抽取次数)
   */
  const dealOneCard = (playerIndex: number) => {
    let randomNum = Math.floor(Math.random() * currentCardList.length)
    let _playerList = [...playerList]
    if (_playerList[playerIndex].cardList.length == 3) {
      MessagePlugin.error('已发三张牌')
      return
    }
    if (_playerList[playerIndex].cardList.length == 0) {
      _playerList[playerIndex].cardList.push(currentCardList[randomNum])
    } else {
      _playerList[playerIndex].cardList.push(currentCardList[randomNum])
    }
    setPlayerList(_playerList)
    substractCard(randomNum)
  }

  /**
   * 结算赢家
   */
  const result = () => {
    // 1 获取所有玩家的牌型
    let _playerList = getPlayerRank()

    // 2 按rank排序
    _playerList.sort((a: PlayerType, b: PlayerType) => { // 
      return a.rank - b.rank
    })

    // 3 把rank一样的拿出来 比较牌面cardNumCompare
    let sameRankList: PlayerType[][] = []
    let sameRank: number = 0
    let rankKindPlayer: PlayerType[]
    for (let i = 1; i <= 6; i++) {
      rankKindPlayer = _playerList.filter((target) => { // 在玩家中找到rank相同的
        return target.rank == i
      })
      if (rankKindPlayer.length > 0) { // 改为rank种类
        sameRankList.push(rankKindPlayer)
        sameRank = i
      }
    }
    console.log('sameRankList', sameRankList)
    console.log('playerList', playerList)

    if (sameRankList.length == 1) { // 全部都是同一牌面
      for (let i = 0; i < sameRankList.length; i++) {
        let res: PlayerType[] = cardNumCompare(sameRankList[i])
        _playerList = res
      }
      console.log('_playerList一样', _playerList)
    } else {
      // 4 list把一样的删掉
      for (let i = 0; i < sameRankList.length; i++) {
        let deleteIndex: number = 0
        let deleteNum: number = 0
        for (let j = 0; j < _playerList.length; j++){
          if (_playerList[j].rank == sameRankList[i][0].rank && deleteIndex == 0) {
            deleteIndex = i
          }
          deleteNum++
        }
        _playerList.splice(deleteIndex, deleteNum)
      }
      console.log('_playerList2', _playerList)
      for (let i = 0; i < sameRankList.length; i++) {
        let res: PlayerType[] = cardNumCompare(sameRankList[i])
        // 5 把排好序的拼接上
        _playerList.push(...res)
        console.log('res', res)
      }
      console.log('_playerList不一样', _playerList)
    }
    // setPlayerList(_playerList)
    setResList(_playerList)
  }

  /**
   * 获取所有玩家的牌型
   */
  const getPlayerRank = () => {
    let _playerList: PlayerType[] = []
    for (let i = 0; i < playerList.length; i++) {
      _playerList[i] = JSON.parse(JSON.stringify(playerList[i]))
    }
    for (let playerIndex = 0; playerIndex < _playerList.length; playerIndex++) {
      let numList: number[] = [] // 一位玩家 3张牌的数字列表
      let flowerList: string[] = [] // 一位玩家 3张牌的花色列表
      for (let cardIndex = 0; cardIndex < _playerList[playerIndex].cardList.length; cardIndex++) {
        numList.push(_playerList[playerIndex].cardList[cardIndex].num)
        flowerList.push(_playerList[playerIndex].cardList[cardIndex].flower)
        _playerList[playerIndex].cardList[cardIndex].flowerWeight = getFlowerWeight(_playerList[playerIndex].cardList[cardIndex].flower)
      }
      if (isBaoziorDuizi(numList).baoziFlag) {
        _playerList[playerIndex].decks = '豹子'
        _playerList[playerIndex].rank = 1
      } else if (isBaoziorDuizi(numList).duiziFlag) {
        _playerList[playerIndex].decks = '对子'
        _playerList[playerIndex].rank = 5
      } else {
        _playerList[playerIndex].decks = '散牌'
        _playerList[playerIndex].rank = 6
      }
      if (isJinhua(flowerList)) {
        _playerList[playerIndex].decks = '金花'
        _playerList[playerIndex].rank = 3
      }
      if (isShunzi(numList)) {
        _playerList[playerIndex].decks = '顺子'
        _playerList[playerIndex].rank = 4
        if (isJinhua(flowerList)) {
          _playerList[playerIndex].decks = '金花顺'
          _playerList[playerIndex].rank = 2
        }
      }
    }
    setPlayerList(_playerList)
    return (_playerList)
  }

  /**
   * [相同牌面]比大小
   * 
   * 分为对子和其他
   * 对子 （比较对子数字大小 => 比较剩下那个数的大小 => 比较对子的最大花色? ）
   * 其他 （3张牌从大到小排序）
   */
  const cardNumCompare = (list: PlayerType[]) => {
    let rank: PlayerType[] = list
    if (list[0].rank == 5) {
      let duiziList: { playerIndex: number, num: number }[] = []
      for (let i = 0; i < list.length; i++) {
        list[i].cardList.sort((a, b) => {
          return b.num - a.num
        })
        let duizi = list[i].cardList[1].num // 中间那个一定是对子中的一个
        duiziList.push({ playerIndex: i, num: duizi })
      }
      duiziList.sort((a, b) => { //返回对子数大小排序
        return b.num - a.num
      })
      console.log('duiziList', duiziList)
      rank = duiziList.map((item) => {
        return list[item.playerIndex]
      })
    }
    else {
      let firstNumList: { playerIndex: number, cardObj: CardType }[] = []
      for (let i = 0; i < list.length; i++) {
        list[i].cardList.sort((a, b) => {
          return b.num - a.num
        })
        let first = list[i].cardList[0].num // 从最大的开始比
        firstNumList.push({ playerIndex: i, cardObj: list[i].cardList[0] })
      }
      firstNumList.sort((a, b) => {
        if (a.cardObj.num == b.cardObj.num) { //数字相同
          return a.cardObj.flowerWeight - b.cardObj.flowerWeight
        } else {
          return b.cardObj.num - a.cardObj.num
        }
      })

      rank = firstNumList.map((item) => {
        return list[item.playerIndex]
      })
    }
    return rank
  }


  /**
   * 是否为豹子或对子(无包含关系，取最大牌面)
   */
  const isBaoziorDuizi = (numList: number[]) => {
    let baoziFlag = false
    let duiziFlag = false
    let res = Array.from(new Set(numList))
    if (res.length == 1) {
      baoziFlag = true
    } else if (res.length == 2) {
      duiziFlag = true
    }
    return { baoziFlag, duiziFlag }
  }

  /**
   * 是否为金花 
   */
  const isJinhua = (flowerList: string[]) => {
    let jinhuaFlag = false
    let res = new Set(flowerList)
    if (res.size == 1) {
      jinhuaFlag = true
    }
    return jinhuaFlag
  }

  /**
   * 是否为顺子
   */
  const isShunzi = (numList: number[]) => {
    let shunziFlag = false
    for (let i = 0; i < numList.length; i++) {
      let linkIndex_min = numList.indexOf((numList[i] - 1))
      let linkIndex_max = numList.indexOf((numList[i] + 1))
      if (linkIndex_min >= 0 && linkIndex_max >= 0 && linkIndex_min != i && linkIndex_max != i) {
        shunziFlag = true
      }
    }
    return shunziFlag
  }

  /**
   * 根据公共牌判断花色的排序
   */
  const getFlowerWeight = (flower: string) => {
    let flowerWeight = 0
    switch (flower) {
      case 'heitao':
        flowerWeight = 4
        break
      case 'hongxing':
        flowerWeight = 3
        break
      case 'meihua':
        flowerWeight = 2
        break
      case 'fangkuai':
        flowerWeight = 1
        break
      default:
        flowerWeight = 1000
    }
    //heitao>hongxing>meihua>fangkuai 4>3>2>1
    if (broardCard.flower == flower) {
      flowerWeight = 10
    }
    return flowerWeight
  }


  // jqk 2==1 j == 10 q == 11 qjk kjq

  // [12, 10, 11] .sort(), [10, 11, 12].reverse() [12, 11, 10]
  // [12, 11, 9] .sort() [9, 11, 12] [12, 11, 9] 
  return <div className='three-ace-win'>
    <div className='player'>
      {initPlayerList()}
      {playerList.length}名玩家
    </div>
    <div className='common'>公共牌：{transferCard(broardCard).flowerString + transferCard(broardCard).numString}
      {!broardCard.num ? <div className='card card-back'></div> : <CardItem card={broardCard} />}
      <div className='deal'>
        {playerList.map((playerItem: PlayerType, playerIndex: number) => {
          return <div className='deal-cardList' key={'deal-cardList' + playerIndex}><Button key={'playerItem' + playerIndex} onClick={() => { dealOneCard(playerIndex) }}>{playerItem.playerName}发牌</Button>
            {playerItem.cardList.map((cardItem: CardType, cardIndex) => {
              return <CardItem key={'cardItem' + cardIndex} card={cardItem} />
            })}
          </div>
        })}
      </div>
    </div>
    <div className='result'>
      {/* {currentCardList.length + (3 * playerList.length) == 51 ? <Button onClick={() => { result() }}>清算</Button> : <></>} */}
      <Button onClick={() => { result() }}>清算</Button>
      {resList.map((playerItem: PlayerType, playerIndex: number) => {
        return <span className='result' key={'result' + playerIndex}>
          {playerIndex != resList.length - 1 ? playerItem.playerName + '  >' : playerItem.playerName}
        </span>
      })}
    </div>
  </div>


}

/**
   * 翻译牌面
   * 传入一个卡片对象，返回一个字符串
   */
const transferCard = (cardObj: CardType) => {
  let numString = ''
  switch (cardObj.num) {
    case 11:
      numString = 'J'
      break
    case 12:
      numString = 'Q'
      break
    case 13:
      numString = 'K'
      break
    case 14:
      numString = 'A'
      break
    default:
      numString = cardObj.num.toString()
  }
  let flowerString = ''
  switch (cardObj.flower) {
    case 'heitao':
      flowerString = '黑桃'
      break
    case 'fangkuai':
      flowerString = '方块'
      break
    case 'meihua':
      flowerString = '梅花'
      break
    case 'hongxin':
      flowerString = '红心'
      break
    default:
      flowerString = ''
  }
  return { numString, flowerString }
}

export {
  ThreeAceWin,
  transferCard
}
